home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / fish / 001-100 / 001-025 / 005 / mandelbrotsrc / mand1.c < prev    next >
C/C++ Source or Header  |  1995-03-17  |  11KB  |  448 lines

  1.  
  2. /*
  3.                    MAND1.C - Graphics routines
  4.              Mandelbrot Self-Squared Dragon Generator
  5.                     For the Commodore Amiga
  6.                          Version 2.01
  7.  
  8.              Copyright (C) 1985, Robert S. French
  9.             Vastly Enhanced by =RJ Mical=  1985/86
  10.             Copyright (C) 1986,  =Robert J. Mical=
  11.                  Placed in the Public Domain
  12.  
  13.  
  14. This program may be distributed free of charge as long as the above
  15. notice is retained.
  16.  
  17. */
  18.  
  19.  
  20. #include "mand.h"
  21.  
  22.  
  23. extern int MathBase, MathTransBase;
  24.  
  25. extern struct Menu MainMenu[MENU_COUNT];
  26. extern struct MenuItem OptionsItems[OPTIONS_COUNT];
  27.  
  28.  
  29. extern SHORT Color0, Color1, Color2;
  30. extern SHORT UserPalette[29];
  31.  
  32. /*----------------------*/
  33. /* Graphics definitions */
  34.  
  35. extern struct   GfxBase       *GfxBase;
  36. extern struct   IntuitionBase *IntuitionBase;
  37.  
  38. extern struct   RastPort      *rp,*rp2;
  39. extern struct   ViewPort      *vp;
  40.  
  41. extern struct   Window        *w,*w2, *ColorWindow;
  42. extern struct   Screen        *screen;
  43. extern struct   IntuiMessage  *message;
  44.  
  45. extern long last_color;
  46.  
  47. extern BOOL SettingCenter, SettingBoxSize, SetBoxProportional;
  48.  
  49. /*----------------------------------*/
  50. /* Miscellaneous Global Definitions */
  51.  
  52. extern union kludge {
  53.    float f;
  54.    int i;
  55. } start_r,end_r,start_i,end_i;  /* Block bounds for set */
  56. extern int max_x,max_y;  /* Graphics window size */
  57. extern int max_count,color_inc,color_offset,color_set,color_mode,color_div;
  58. extern int color_inset,func_num;
  59.  
  60. extern int v_starty,max_mem;
  61. extern long v_offset;
  62. extern UWORD *color_table,*v_mand_store;
  63.  
  64. extern int modified,want_read;
  65.  
  66. extern FILE *console,*v_fp,*redir_fp;
  67.  
  68. extern SHORT ZoomCenterX, ZoomCenterY, ZoomBoxSizeX, ZoomBoxSizeY;
  69. extern SHORT ZoomBoxStartX, ZoomBoxStartY;
  70.  
  71.  
  72. /*----------------*/
  73. /* Color routines */
  74.  
  75. init_colors()
  76. {
  77.    switch (color_set) {
  78.       case 0: init_cincr(); break;
  79.       case 1: init_c7rot(); break;
  80.       case 2: copy_userpalette(); break;
  81.    }
  82. }
  83.  
  84. init_cincr()
  85. /* this routine initializes the color table with sequential values from
  86.  * 0 to 4095
  87.  */
  88. {
  89.    UWORD i;
  90.  
  91.    for (i=0;i<4096;i++)
  92.       *(color_table + i) = i;
  93. }
  94.  
  95.  
  96. init_c7rot()
  97. /* this routine initializes the color table with this pattern:
  98.  * 0 = 0
  99.  * 1-15 = unit steps of blue
  100.  * 16-30 = unit steps of green
  101.  * 31-45 = unit steps of red
  102.  * 46-60 = unit steps of sky sky blue (blue and green)
  103.  * 61-75 = unit steps of purple (blue and red)
  104.  * 76-90 = unit steps of yellow (green and red)
  105.  * 91-115 = unit steps of white (all colors)
  106.  */
  107. {
  108.    UWORD i,j,*base;
  109.  
  110.    base = color_table;
  111.    *(base++) = 0;
  112.  
  113.    for (j = 0; j < 39; j++) {
  114.       for (i = 1; i < 16; i++)
  115.          *(base++) = i; /* gimme the blues */
  116.       for (i = 1; i < 16; i++)
  117.          *(base++) = i << 4; /* these are the greens */
  118.       for (i = 1; i < 16; i++)
  119.          *(base++) = i << 8; /* the reds */
  120.       for (i = 1; i < 16; i++)
  121.          *(base++) = i | (i << 4); /* blue and green */
  122.       for (i = 1; i < 16; i++)
  123.          *(base++) = i | (i << 8); /* blue and red */
  124.       for (i = 1; i < 16; i++)
  125.          *(base++) = (i << 4) | (i << 8); /* green and red */
  126.       for (i = 1; i < 16; i++)
  127.          *(base++) = i | (i << 4) | (i << 8); /* all three */
  128.    }
  129. }
  130.  
  131.  
  132. copy_userpalette()
  133. {
  134.     SHORT i;
  135.  
  136.     for (i = 0; i <= 28; i++)
  137.     *(color_table + color_offset + (i + 1) * color_inc) = UserPalette[i];
  138. }
  139.  
  140.  
  141. gen_mand()
  142. {
  143.    void write_out();
  144.  
  145.    int x_coord,y_coord,count;
  146.    union kludge x_gap,y_gap,z_r,z_i,u_r,u_i,temp,temp2,temp3,const0;
  147.    union kludge const1,const2,const12;
  148.    ULONG class;
  149.    USHORT code;
  150.    int returncode;
  151.    int z_r_squared, z_i_squared;
  152.  
  153.     /* if there was a display open, close it now */
  154.    CloseDisplay();
  155.  
  156.    /* show the current settings! */
  157.    CurrentSettings();
  158.  
  159.    /* reset the display variables: */
  160.    SettingCenter = SettingBoxSize = FALSE;
  161.  
  162.    if (v_fp) {
  163.       fclose(v_fp);
  164.       v_fp = NULL;
  165.    }
  166.  
  167.    v_fp = fopen("Mandelbrot.temp.file","w+");
  168.    if (v_fp == NULL) {
  169.       abort("Can't open temporary file!");
  170.    }
  171.  
  172.    v_starty = 1;
  173.    v_offset = 0L;
  174.    modified = FALSE;
  175.    want_read = FALSE;
  176.    ZoomCenterX = (max_x >> 1);
  177.    ZoomCenterY = (max_y >> 1);
  178.    ZoomBoxSizeX = max_x;
  179.    ZoomBoxSizeY = max_y;
  180.  
  181.    if (open_winds())
  182.       {
  183.       returncode = 1;
  184.       goto OPEN_W_RETURN;
  185.       }
  186.  
  187.    x_gap.i = SPDiv(SPFlt(max_x),SPSub(start_r.i,end_r.i));
  188.    y_gap.i = SPDiv(SPFlt(max_y),SPSub(start_i.i,end_i.i));
  189.  
  190.    const0.i = SPFlt(0);
  191.    const1.i = SPFlt(1);
  192.    const2.i = SPFlt(2);
  193.    const12.i = SPDiv(SPFlt(2),SPFlt(1));
  194.  
  195.    for (y_coord = 0; y_coord < max_y; y_coord++)
  196.       {
  197.       last_color = 0xfff;
  198.       v_pos_line(y_coord);
  199.       modified = TRUE;
  200.       for (x_coord = 0; x_coord < max_x; x_coord++)
  201.          {
  202.          while (message = (struct IntuiMessage *)GetMsg(w->UserPort))
  203.             {
  204.             class = message->Class;
  205.             code  = message->Code;
  206.             ReplyMsg(message);
  207.             if (class == MENUPICK)
  208.                {
  209.                /* the menu strip is hacked up to a minimal set during gen_m */
  210.                switch MENUNUM(code)
  211.                   {
  212.                   case 0:
  213.                      switch ITEMNUM(code)
  214.                         {
  215.                         case 0:
  216.                            returncode = 0;
  217.                goto OPEN_W_RETURN;
  218.                         case 1:
  219.                            CloseDisplay();
  220.                            fclose(v_fp);
  221.                            v_fp = NULL;
  222.                            returncode = 1;
  223.                goto OPEN_W_RETURN;
  224.                         }
  225.                      break;
  226.                   }
  227.                }
  228.             }
  229.  
  230.          if (func_num == 0)
  231.             z_r.i = const0.i;
  232.          else
  233.             z_r.i = const12.i;
  234.  
  235.          z_i.i = const0.i;
  236.          u_r.i = SPAdd(start_r.i,SPMul(SPFlt(x_coord),x_gap.i));
  237.          u_i.i = SPAdd(start_i.i,SPMul(SPFlt(max_y-y_coord-1),y_gap.i));
  238.          for (count = 0; count < max_count; count++)
  239.             {
  240.         /* By setting these variables and reusing the results below,
  241.          * we save approximately 10% execution time in this 
  242.          * innermost of inner loops.
  243.          */
  244.             z_r_squared = SPMul(z_r.i, z_r.i);
  245.         z_i_squared = SPMul(z_i.i, z_i.i);
  246.             if ( SPFix(SPAdd(z_r_squared, z_i_squared)) >= 4 ) break;
  247.             if (func_num == 0)
  248.                {  /* z = z^2-u */
  249.                temp.i = SPSub(u_r.i, SPSub(z_i_squared, z_r_squared));
  250.                z_i.i = SPSub(u_i.i, SPMul(SPMul(const2.i,z_r.i), z_i.i));
  251.                z_r = temp;
  252.                }
  253.             else if (func_num == 1)
  254.                {  /* z = uz(1-z) */
  255.                temp2.i = SPSub(z_r.i,const1.i);
  256.                temp3.i = SPNeg(z_i.i);
  257.                temp.i = SPSub(SPMul(temp3.i,z_i.i),SPMul(temp2.i,z_r.i));
  258.                z_i.i = SPAdd(SPMul(temp2.i,z_i.i),SPMul(temp3.i,z_r.i));
  259.                z_r = temp;
  260.                temp.i = SPSub(SPMul(z_i.i,u_i.i),SPMul(z_r.i,u_r.i));
  261.                z_i.i = SPAdd(SPMul(z_r.i,u_i.i),SPMul(z_i.i,u_r.i));
  262.                z_r = temp;
  263.                }
  264.             }
  265.  
  266.          if (count >= max_count)
  267.             count = 0;
  268.          *(v_mand_store+(y_coord-v_starty)*max_x+x_coord) = count;
  269.          write_out(count,x_coord,y_coord);
  270.          }
  271.  
  272.    }
  273.  
  274.    /* successful return with window opened */
  275.    returncode = 0;
  276.    DisplayBeep(NULL); /* hey, we're done! */
  277.    /* Now that we're drawing the primary display, 
  278.     * restore the entire menu system 
  279.     */
  280.  
  281. OPEN_W_RETURN:
  282.    if (returncode == 0)
  283.       {
  284.       MainMenu[MENU_OPTIONS].NextMenu = &MainMenu[MENU_ZOOM];
  285.       MainMenu[MENU_OPTIONS].FirstItem = &OptionsItems[0];
  286.       SetMenuStrip(w, &MainMenu[0]);
  287.       }
  288.  
  289.    return(returncode);
  290. }
  291.  
  292. disp_mand()
  293. {
  294.    void write_out();
  295.  
  296.    int x_coord,y_coord,count;
  297.  
  298.    if (open_winds())
  299.       return (1);
  300.  
  301.    want_read = TRUE;
  302.  
  303.    for (y_coord=0;y_coord<max_y;y_coord++) {
  304.       last_color = 0xfff;
  305.       v_pos_line(y_coord);
  306.       for (x_coord=0;x_coord<max_x;x_coord++) {
  307.          count = *(v_mand_store+(y_coord-v_starty)*max_x+x_coord);
  308.          write_out(count,x_coord,y_coord);
  309.       }
  310.    }
  311.  
  312.    return (0);
  313. }
  314.  
  315. void write_out(count,x,y)
  316. int count,x,y;
  317. {
  318.    void ham_write();
  319.    SHORT modulus;
  320.    int color;
  321.  
  322.    y += STARTY;
  323.  
  324.    if (!(color_mode & NOT_HOLDANDMODIFY)) {
  325.       if (count == 0)
  326.          color = color_inset;
  327.       else
  328.          color = count * color_inc + color_offset;
  329.       ham_write(*(color_table+color),x,y);
  330.    }
  331.    else /* we're not hold-and-modify, so ... */ {
  332.       if (color_mode & HIRES_MODE) modulus = 13;
  333.       else modulus = 29;
  334.  
  335.       if (count == 0) color = 2;
  336.       else color = (((count - 1) / color_div) % modulus) + 3;
  337.       SetAPen(rp, color);
  338.       WritePixel(rp, x, y);
  339.    }
  340. }
  341.  
  342. void ham_write(color, x, y)
  343. int color;
  344. int x, y;
  345. {
  346.    if ((color & 0xf00) != (last_color & 0xf00)) {
  347.       SetAPen(rp,((color & 0xf00) >> 8) + 0x20);
  348.       WritePixel(rp,x,y);
  349.       last_color = (last_color & 0xff) | (color & 0xf00);
  350.       return;
  351.    }
  352.  
  353.    if ((color & 0xf0) != (last_color & 0xf0)) {
  354.       SetAPen(rp,((color & 0xf0) >> 4) + 0x30);
  355.       WritePixel(rp,x,y);
  356.       last_color = (last_color & 0xf0f) | (color & 0xf0);
  357.       return;
  358.    }
  359.  
  360.    SetAPen(rp,(color & 0xf) + 0x10);
  361.    WritePixel(rp,x,y);
  362.    last_color = (last_color & 0xff0) | (color & 0xf);
  363.    return;
  364. }
  365.  
  366.  
  367. DrawZoomCenter()
  368. {
  369.     DrawCross(ZoomCenterX, ZoomCenterY);
  370. }
  371.  
  372. DrawDisplayCenter()
  373. {
  374.     DrawCross(max_x >> 1, max_y >> 1);
  375. }
  376.  
  377.  
  378. DrawCross(x, y)
  379. SHORT x, y;
  380. {
  381.    SetDrMd(w->RPort, COMPLEMENT);
  382.    Move(w->RPort, 0, y);
  383.    Draw(w->RPort, max_x, y);
  384.    Move(w->RPort, x, 0);
  385.    Draw(w->RPort, x, max_y);
  386. }
  387.  
  388.  
  389. RecalcZoomBox()
  390. {
  391.     ZoomBoxSizeY = (abs(w->MouseY - ZoomCenterY) << 1) + 1;
  392.     if (w->MouseY < ZoomCenterY) ZoomBoxStartY = w->MouseY;
  393.     else ZoomBoxStartY = ZoomCenterY - ((ZoomBoxSizeY - 1) >> 1);
  394.  
  395.     /* if SetBoxProportional, size X proportional to Y */
  396.     if (SetBoxProportional)
  397.     {
  398.     ZoomBoxSizeX = (ZoomBoxSizeY * 8) / 5;
  399.     ZoomBoxStartX = ZoomCenterX - ((ZoomBoxSizeX - 1) >> 1);
  400.     }
  401.     else
  402.     {
  403.     ZoomBoxSizeX = (abs(w->MouseX - ZoomCenterX) << 1) + 1;
  404.     if (w->MouseX < ZoomCenterX) ZoomBoxStartX = w->MouseX;
  405.     else ZoomBoxStartX = ZoomCenterX - ((ZoomBoxSizeX - 1) >> 1);
  406.     }
  407. }
  408.  
  409.  
  410. DrawZoomBox()
  411. {
  412.    SetDrMd(w->RPort, COMPLEMENT);
  413.    DrawBox(w->RPort, ZoomBoxStartX, ZoomBoxStartY, 
  414.          ZoomBoxStartX + ZoomBoxSizeX - 1,
  415.          ZoomBoxStartY + ZoomBoxSizeY - 1);
  416.  
  417. }
  418.  
  419.  
  420. CloseDisplay()
  421. {
  422.    if (w) CloseWindow(w);
  423.    if (w2) CloseWindow(w2);
  424.    if (ColorWindow) CloseWindow(ColorWindow);
  425.    if (screen) CloseScreen(screen);
  426.    w = NULL;
  427.    screen = NULL;
  428. }
  429.  
  430.  
  431.  
  432. DrawBox(rp, x1, y1, x2, y2)
  433. struct RastPort *rp;
  434. SHORT x1, y1, x2, y2;
  435. /* draws a box without overlapping the edges (in case of complement mode) */
  436. {
  437.     Move(rp, x1, y1 + SIGN(y2 - y1));
  438.     Draw(rp, x1, y2);  
  439.     Move(rp, x1 + SIGN(x2 - x1), y2);
  440.     Draw(rp, x2, y2);  
  441.     Move(rp, x2, y2 - SIGN(y2 - y1));
  442.     Draw(rp, x2, y1); 
  443.     Move(rp, x2 - SIGN(x2 - x1), y1);
  444.     Draw(rp, x1, y1);
  445. }
  446.  
  447.  
  448.